home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / MCASM.RAR / MC_ASM.EXE / WROX_ASM / CH10 / PROGRAMS / DARHH7.ASM < prev    next >
Assembly Source File  |  1994-05-30  |  10KB  |  613 lines

  1. ; Haffman decoding
  2. ; Written by Malakhov K.A.
  3. ; Compile with TASM 3.0 or latter
  4. ;         TASM DARHH7.ASM /MX /ZX /O
  5. ; CALL:    haff_decode(char *buffinput,unsigned int inputlength,
  6. ;            char *buffoutput,unsigned int outputlength);
  7.  
  8. model large
  9.  
  10. PUBLIC    _haff_decode
  11.  
  12. .code
  13.  
  14. _haff_decode    PROC    C FAR
  15.         ARG    buffi:dword,ileng:word,buffo:dword,oleng:word
  16.         USES    ds,es,di,si,bx,cx,dx
  17.  
  18. ; main
  19. ; Allocate memory
  20.         mov    ah,48h
  21.         mov    bx,2049
  22.         int    21h
  23.         jnc    @@impl_t000
  24.         jmp    @@imp_err
  25. @@impl_t000:    mov    cs:seg1,ax
  26.         mov    ah,48h
  27.         mov    bx,2049
  28.         int    21h
  29.         jnc    @@impl_t001
  30.         jmp    @@imp_err
  31. @@impl_t001:    mov    cs:seg2,ax
  32.         jmp    @@main_1
  33. @@main_0:    jmp    @@imp_err
  34. @@main_1:    mov    ax,word ptr buffi+2
  35.         mov    ds,ax
  36.         mov    si,word ptr buffi
  37.         mov    ax,ileng
  38.         cmp    ax,0
  39.         ja    @@new_010
  40.         jmp    @@imp_err
  41. @@new_010:    mov    cs:counti,ax
  42.         mov    ax,word ptr buffo+2
  43.         mov    es,ax
  44.         mov    di,word ptr buffo
  45.         mov    ax,oleng
  46.         mov    cs:counto,ax
  47.         cmp    ax,0
  48.         ja    @@imp_005
  49.         jmp    @@imp_err
  50. @@imp_005:
  51. ; decompression
  52.         call    darhhaff
  53.         cmp    ax,0
  54.         jne    @@implode_e1
  55. @@implode_e:    jmp    @@imp_err
  56. @@implode_e1:    jmp    @@imp_exit
  57.  
  58. darhhaff    proc    NEAR
  59. ; Read
  60.         lodsb
  61.         dec    word ptr cs:counti
  62.         push    ax
  63.         cmp    cs:counti,0
  64.         pop    ax
  65.         jne    @@darh_001
  66.         jmp    @@implode_err
  67. @@darh_001:    mov    cs:CRCodr,al
  68.         lodsb
  69.         dec    word ptr cs:counti
  70.         push    ax
  71.         cmp    cs:counti,0
  72.         pop    ax
  73.         jne    @@darh_010
  74.         jmp    @@implode_err
  75. ; Read the length of header
  76. @@darh_010:    xor    ah,ah
  77.         inc    ax
  78.         mov    cs:hafflen,ax
  79.         mov    dx,ax
  80.         push    cs
  81.         pop    es
  82. ; Clear tresh
  83.         mov    cx,256
  84.         lea    di,chartab
  85.         xor    ax,ax
  86.     rep    stosb
  87.         mov    cx,256
  88.         lea    di,freqtab
  89.     rep    stosw
  90.         mov    cx,1024
  91.         lea    di,hafftab
  92.     rep    stosb
  93.         mov    cx,dx
  94.         mov    cs:codcnt,0
  95. ; Read header chartab
  96.         lea    di,chartab
  97. @@darh_020:    lodsb
  98.         dec    word ptr cs:counti
  99.         push    ax
  100.         cmp    cs:counti,0
  101.         pop    ax
  102.         ja    @@darh_030
  103.         jmp    @@implode_err
  104. @@darh_030:    stosb
  105.         loop    @@darh_020
  106. ; Read header freqtab
  107.         mov    cx,cs:hafflen
  108.         lea    di,freqtab
  109. @@darh_040:    lodsb
  110.         dec    word ptr cs:counti
  111.         push    ax
  112.         cmp    cs:counti,0
  113.         pop    ax
  114.         ja    @@darh_050
  115.         jmp    @@implode_err
  116. @@darh_050:    xchg    ah,al
  117.         lodsb
  118.         dec    word ptr cs:counti
  119.         push    ax
  120.         cmp    cs:counti,0
  121.         pop    ax
  122.         ja    @@darh_055
  123.         jmp    @@implode_err
  124. @@darh_055:    xchg    ah,al
  125.         stosw
  126.         loop    @@darh_040
  127. @@darh_057:
  128.         mov    cs:savesi,si
  129. ; Build the tree
  130. ; Prepare the table of weights
  131.         mov    cx,256
  132.         lea    di,codtab
  133.         xor    al,al
  134.     rep    stosb
  135. ; MIN
  136. @@impl_089:    mov    bx,65535
  137.         xor    si,si
  138.         mov    cx,cs:hafflen
  139. @@impl_090:    mov    ax,cs:freqtab[si]
  140.         cmp    ax,0
  141.         je    @@impl_092
  142.         cmp    bx,ax
  143.         jbe    @@impl_092
  144.         mov    bx,ax
  145.         mov    cs:minpos1,si
  146. @@impl_092:    add    si,2
  147.         loop    @@impl_090
  148.  
  149.         mov    cs:exit,1
  150.         mov    bx,65535
  151.         xor    si,si
  152.         mov    cx,cs:hafflen
  153.         cmp    cx,1
  154.         ja    @@impl_094
  155.         mov    ax,cs:minpos1
  156.         shr    ax,1
  157.         mov    cl,1
  158.         call    shift
  159.         jmp    @@impl_220
  160. @@impl_094:    mov    ax,cs:freqtab[si]
  161.         cmp    ax,0
  162.         je    @@impl_096
  163.         cmp    bx,ax
  164.         jb    @@impl_096
  165.         cmp    si,cs:minpos1
  166.         je    @@impl_096
  167.         mov    bx,ax
  168.         mov    cs:exit,0
  169.         mov    cs:minpos2,si
  170. @@impl_096:    add    si,2
  171.         loop    @@impl_094
  172.  
  173.         mov    al,cs:exit
  174.         cmp    al,0
  175.         je    @@impl_098
  176.         jmp    @@impl_220
  177. @@impl_098:
  178.         mov    ax,cs:minpos1
  179.         shr    ax,1
  180.         mov    si,ax
  181.         mov    ax,cs:minpos2
  182.         shr    ax,1
  183.         mov    di,ax
  184.         mov    al,cs:codtab[si]
  185.         mov    ah,cs:codtab[di]
  186.         cmp    al,0
  187.         jne    @@impl_100
  188.         cmp    ah,0
  189.         je    @@impl_099
  190.         jmp    @@impl_125
  191. ; Variant 1
  192. @@impl_099:    inc    byte ptr cs:codcnt
  193.         mov    ax,si
  194.         mov    cl,0
  195.         call    shift
  196.         mov    ax,di
  197.         mov    cl,1
  198.         call    shift
  199.         mov    al,cs:codcnt
  200.         mov    cs:codtab[si],al
  201.         mov    cs:codtab[di],al
  202.         mov    si,cs:minpos1
  203.         mov    di,cs:minpos2
  204.         mov    ax,cs:freqtab[di]
  205.         add    cs:freqtab[si],ax
  206.         mov    cs:freqtab[di],0
  207.         jmp    @@impl_089
  208. ; Variant 2
  209. @@impl_100:
  210.         cmp    ah,0
  211.         je    @@impl_102
  212.         jmp    @@impl_140
  213. @@impl_102:
  214.         mov    ax,cs:minpos1
  215.         shr    ax,1
  216.         mov    si,ax
  217.         mov    dl,cs:codtab[si]
  218.         mov    cx,256
  219.         xor    si,si
  220. @@impl_105:    cmp    dl,cs:codtab[si]
  221.         jne    @@impl_110
  222.         push    cx
  223.         mov    ax,si
  224.         xor    cl,cl
  225.         call    shift
  226.         pop    cx
  227. @@impl_110:    inc    si
  228.         loop    @@impl_105
  229.  
  230.         mov    ax,cs:minpos2
  231.         shr    ax,1
  232.         mov    cl,1
  233.         call    shift
  234.  
  235.         mov    ax,cs:minpos1
  236.         shr    ax,1
  237.         mov    si,ax
  238.         mov    ax,cs:minpos2
  239.         shr    ax,1
  240.         mov    di,ax
  241.         mov    al,cs:codtab[si]
  242.         mov    cs:codtab[di],al
  243.  
  244.         mov    si,cs:minpos1
  245.         mov    di,cs:minpos2
  246.         mov    ax,cs:freqtab[di]
  247.         add    cs:freqtab[si],ax
  248.         mov    cs:freqtab[di],0
  249.         jmp    @@impl_089
  250. @@impl_125:
  251.         mov    ax,cs:minpos2
  252.         shr    ax,1
  253.         mov    si,ax
  254.         mov    dl,cs:codtab[si]
  255.         mov    cx,256
  256.         xor    si,si
  257. @@impl_130:    cmp    dl,cs:codtab[si]
  258.         jne    @@impl_135
  259.         push    cx
  260.         mov    ax,si
  261.         xor    cl,cl
  262.         call    shift
  263.         pop    cx
  264. @@impl_135:    inc    si
  265.         loop    @@impl_130
  266.  
  267.         mov    ax,cs:minpos1
  268.         shr    ax,1
  269.         mov    cl,1
  270.         call    shift
  271.  
  272.         mov    ax,cs:minpos2
  273.         shr    ax,1
  274.         mov    si,ax
  275.         mov    ax,cs:minpos1
  276.         shr    ax,1
  277.         mov    di,ax
  278.         mov    al,cs:codtab[si]
  279.         mov    cs:codtab[di],al
  280.  
  281.         mov    si,cs:minpos2
  282.         mov    di,cs:minpos1
  283.         mov    ax,cs:freqtab[di]
  284.         add    cs:freqtab[si],ax
  285.         mov    cs:freqtab[di],0
  286.         jmp    @@impl_089
  287. ; Variant 3
  288. @@impl_140:
  289.         mov    ax,cs:minpos1
  290.         shr    ax,1
  291.         mov    si,ax
  292.         mov    dl,cs:codtab[si]
  293.         mov    cx,256
  294.         xor    si,si
  295. @@impl_145:    cmp    dl,cs:codtab[si]
  296.         jne    @@impl_150
  297.         push    cx
  298.         mov    ax,si
  299.         xor    cl,cl
  300.         call    shift
  301.         pop    cx
  302. @@impl_150:    inc    si
  303.         loop    @@impl_145
  304.  
  305.         mov    ax,cs:minpos2
  306.         shr    ax,1
  307.         mov    si,ax
  308.         mov    dl,cs:codtab[si]
  309.         mov    cx,256
  310.         xor    si,si
  311. @@impl_155:    cmp    dl,cs:codtab[si]
  312.         jne    @@impl_160
  313.         push    cx
  314.         mov    ax,si
  315.         mov    cl,1
  316.         call    shift
  317.         pop    cx
  318. @@impl_160:    inc    si
  319.         loop    @@impl_155
  320.  
  321.         mov    ax,cs:minpos1
  322.         shr    ax,1
  323.         mov    si,ax
  324.         mov    dl,cs:codtab[si]
  325.         mov    ax,cs:minpos2
  326.         shr    ax,1
  327.         mov    si,ax
  328.         mov    dh,cs:codtab[si]
  329.         mov    cx,256
  330.         xor    si,si
  331. @@impl_165:    cmp    dl,cs:codtab[si]
  332.         jne    @@impl_170
  333.         mov    cs:codtab[si],dh
  334. @@impl_170:    inc    si
  335.         loop    @@impl_165
  336.  
  337.         mov    si,cs:minpos2
  338.         mov    di,cs:minpos1
  339.         mov    ax,cs:freqtab[di]
  340.         add    cs:freqtab[si],ax
  341.         mov    cs:freqtab[di],0
  342.         jmp    @@impl_089
  343. ; Calculating the number of bytes
  344. @@impl_220:    mov    di,2
  345.         mov    cx,256
  346. @@impl_230:    mov    al,cs:hafftab[di]
  347.         xor    ah,ah
  348.         xor    dx,dx
  349.         mov    bx,8
  350.         div    bx
  351.         mov    cs:hafftab[di],8
  352.         cmp    dx,0
  353.         je    @@impl_240
  354.         mov    cs:hafftab[di],dl
  355.         inc    ax
  356. @@impl_240:    mov    cs:hafftab[di+1],al
  357.         add    di,4
  358.         loop    @@impl_230
  359. ; The number of dearchieve bytes
  360.         mov    cx,256
  361.         mov    ax,es
  362.         mov    ds,ax
  363.         lea    si,freqtab
  364.         mov    cs:countb,0
  365. @@impl_245:    lodsw
  366.         add    cs:countb,ax
  367.         loop    @@impl_245
  368. ; To fill the table
  369.         mov    cx,256
  370.         mov    ax,cs:seg1
  371.         mov    ds,ax
  372.         mov    ax,cs:seg2
  373.         mov    es,ax
  374.         xor    si,si
  375. @@impl_t010:    push    cx
  376. ; Mask
  377.         mov    dl,byte ptr cs:hafftab[si+3]
  378.         cmp    dl,0
  379.         je    @@impl_t040
  380.         mov    ax,0ffffh
  381.         mov    cl,3
  382.         shl    dl,cl
  383.         mov    cl,24
  384.         sub    cl,dl
  385.         sub    cl,byte ptr cs:hafftab[si+2]
  386.         shl    ax,cl
  387.         mov    cs:svsi,ax
  388. ; Word
  389.         mov    dh,byte ptr cs:hafftab[si]
  390.         mov    dl,byte ptr cs:hafftab[si+1]
  391.         mov    cs:svdi,dx
  392.  
  393. @@impl_t020:    mov    ax,cs:svsi
  394.         and    ax,dx
  395.         cmp    ax,cs:svdi
  396.         jne    @@impl_t040
  397.         mov    bx,dx
  398. ; Direction betwin memory blocks
  399.         cmp    bx,32768
  400.         ja    @@impl_t030
  401.         mov    ax,si
  402.         shr    ax,1
  403.         shr    ax,1
  404.         mov    byte ptr ds:[bx],al
  405.         inc    dx
  406.         jmp    short @@impl_t020
  407. @@impl_t030:    sub    bx,32768
  408.         mov    ax,si
  409.         shr    ax,1
  410.         shr    ax,1
  411.         mov    byte ptr es:[bx],al
  412.         inc    dx
  413.         jmp    short @@impl_t020
  414. @@impl_t040:    add    si,4
  415.         pop    cx
  416.         loop    @@impl_t010
  417. ; Decoder
  418.         mov    cs:shiftb,0
  419.         mov    ax,oleng
  420.         mov    cs:counto,ax
  421.         mov    ax,word ptr buffi+2
  422.         mov    ds,ax
  423.         mov    si,cs:savesi
  424.         mov    ax,word ptr buffo+2
  425.         mov    es,ax
  426.         mov    di,word ptr buffo
  427.         mov    cs:CRCod,0
  428. ; Load the word
  429. @@impl_250:    mov    ah,ds:[si]
  430.         mov    al,ds:[si+1]
  431.         mov    dh,al
  432.         mov    dl,ds:[si+2]
  433. ; Shift
  434. @@impl_254:    mov    cl,cs:shiftb
  435.         shl    ax,cl
  436.         shl    dx,cl
  437.         mov    al,dh
  438.  
  439.         mov    bx,ax
  440.         cmp    bx,32768
  441.         ja    @@impl_p010
  442.         mov    cx,cs:seg1
  443.         jmp    short @@impl_p020
  444. @@impl_p010:    sub    bx,32768
  445.         mov    cx,cs:seg2
  446. @@impl_p020:    push    ds
  447.         mov    ds,cx
  448.         mov    al,byte ptr ds:[bx]
  449.         pop    ds
  450.         mov    cs:svsi,si
  451.         xor    ah,ah
  452.         mov    si,ax
  453. ; Output from loop (found)
  454. @@impl_315:
  455.         stosb
  456.         add    cs:CRCod,al
  457.         dec    word ptr cs:counto
  458.         mov    ax,cs:counto
  459.         cmp    ax,0
  460.         ja    @@impl_312
  461.         jmp    @@implode_err
  462. @@impl_312:    dec    word ptr cs:countb
  463.         mov    bx,si
  464.         mov    si,cs:svsi
  465.         mov    cl,2
  466.         shl    bx,cl
  467.         add    bx,3
  468.         mov    al,cs:hafftab[bx]
  469.         dec    al
  470.         xor    ah,ah
  471.         add    si,ax
  472.         sub    word ptr cs:counti,ax
  473.         mov    al,cs:hafftab[bx-1]
  474.         mov    ah,cs:shiftb
  475.         add    ah,al
  476.  
  477.         mov    cx,cs:countb
  478.         cmp    cx,0
  479.         je    @@impl_318
  480.  
  481.         cmp    ah,8
  482.         jb    @@impl_314
  483.         sub    ah,8
  484.         inc    si
  485.         dec    word ptr cs:counti
  486. @@impl_314:    mov    cs:shiftb,ah
  487.         jmp    @@impl_250
  488. ; Output
  489.  
  490. @@impl_318:
  491. @@impl_320:    mov    ax,oleng
  492.         sub    ax,cs:counto
  493.         cmp    ax,0
  494.         ja    @@impl_330
  495.         inc    ax
  496. @@impl_330:
  497. @@implode_err:    mov    ax,0
  498.         jmp    short @@impl_exit
  499. @@implode_noerr:
  500. ; Check CRC
  501.         mov    bl,cs:CRCodr
  502.         cmp    bl,cs:CRCod
  503.         je    @@impl_exit
  504.         mov    ax,0
  505. @@impl_exit:    ret
  506. darhhaff    endp
  507.  
  508. ; Procedure for set a mask
  509. maska        proc    NEAR
  510.         push    bx
  511.         push    cx
  512.         push    dx
  513.         mov    bx,si
  514.         mov    cl,2
  515.         shl    bx,cl
  516.         add    bx,3
  517.         cmp    dl,cs:hafftab[bx]
  518.         jne    @@maska_010
  519.         dec    bx
  520.         mov    cl,8
  521.         sub    cl,cs:hafftab[bx]
  522.         mov    dl,0ffh
  523.         shl    dl,cl
  524.         and    ah,dl
  525. @@maska_010:    pop    dx
  526.         pop    cx
  527.         pop    bx
  528.         ret
  529. maska        endp
  530.  
  531. ; Shift procedure
  532. shift        proc    NEAR
  533.         push    bx
  534.         push    di
  535.         push    dx
  536.         rcr    cl,1
  537.         pushf
  538.         mov    bx,ax
  539.         mov    al,cs:chartab[bx]
  540.         xor    ah,ah
  541.         mov    cl,2
  542.         shl    ax,cl
  543.         mov    di,ax
  544.         xor    bx,bx
  545.         mov    dx,bx
  546.         add    dx,1
  547. @@shift_010:    cmp    bx,dx
  548.         ja    @@shift_020
  549.         mov    al,cs:hafftab[di+bx]
  550.         popf
  551.         rcr    al,1
  552.         pushf
  553.         mov    cs:hafftab[di+bx],al
  554.         inc    bx
  555.         jmp    short @@shift_010
  556. @@shift_015:    mov    cs:errflag,1
  557.         jmp    short @@shift_030
  558. @@shift_020:    popf
  559.         mov    cl,byte ptr cs:hafftab[di+bx]
  560.         cmp    cl,16
  561.         ja    @@shift_015
  562. @@shift_030:    inc    byte ptr cs:hafftab[di+bx]
  563.         pop    dx
  564.         pop    di
  565.         pop    bx
  566.         ret
  567. shift        endp
  568.  
  569. ; Data
  570. counti        dw    ?    ; Input bytes
  571. counto        dw    ?       ; Output bytes
  572. countb        dw    ?    ; Counter of bytes
  573. savesi        dw    ?
  574. hafflen        dw    ?
  575. errflag        db    ?
  576. shiftb        db    ?
  577. currhaff    dw    ?
  578. minpos1        dw    ?
  579. minpos2        dw    ?
  580. codcnt        db    ?
  581. exit        db    ?
  582. kajuk        dw    ?
  583. ident        db    'MSI'
  584. CRCod        db    ?
  585. CRCodr        db    ?
  586. flag        dw    ?
  587. svsi        dw    ?
  588. svdi        dw    ?
  589. seg1        dw    ?    ; Address of heshing table
  590. seg2        dw    ?    ;
  591. chartab        db    256 dup(?)
  592. freqtab        dw    256 dup(?)
  593. codtab        db    256 dup(?)
  594. hafftab        db    1024 dup(?)
  595.  
  596. @@imp_err:    mov    ax,0
  597.         jmp    short @@imp_exit
  598. @@imp_noerr:
  599. @@imp_exit:    push    ax
  600.         mov    ax,cs:seg1
  601.         mov    es,ax
  602.         mov    ah,49h
  603.         int    21h
  604.         mov    ax,cs:seg2
  605.         mov    es,ax
  606.         mov    ah,49h
  607.         int    21h
  608.         pop    ax
  609.         ret
  610. _haff_decode    ENDP
  611.  
  612.         END
  613.